package com.news.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.news.common.*;
import com.news.dto.NewsNumber;
import com.news.entity.*;
import com.news.service.*;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 新闻表 前端控制器
 * </p>
 *
 */
@Controller
@RequestMapping({"/news","/home/news"})
public class SysNewsController {

    private static  final Logger logger= LoggerFactory.getLogger(SysNewsController.class);
    
    @Autowired
    SysNewsService newsService;

    @Autowired
    CheckNewsService checkNewsService;

    @Autowired
    NewsCategoryService newsCategoryService;

    @Autowired
    UserAttentionService attentionService;

    @Autowired
    NewsFavorService favorService;

    @Autowired
    SysUserService userService;

    @Autowired
    NewsForwardService forwardService;

    @Autowired
    NewsCommentService commentService;

    @Value("${com.cgx.file.baseFilePath}")
    private String baseFilePath;

//    private static String schema="https";
//
//    private static String baseurl="https://www.toutiao.com/";
//
//    private static  String yuleUrl="https://www.toutiao.com/ch/news_entertainment/";


    //获取新闻分类
    @ModelAttribute
    public void addModelAttribute(Model model){
        List<NewsCategory> categoryList = newsCategoryService.list();
        model.addAttribute("categoryList",categoryList);
    }

    /**
     * 获取网络图片保存到本地
     * */
    public String  saveFileByUrl(String imgUrl) throws IOException {
        //创建io流
        FileOutputStream out = null;
        BufferedInputStream in = null;
        HttpURLConnection connection = null;
        //创建缓冲区
        byte[] buf = new byte[1024];
        int len = 0;
        //文件名字，随机一个id，并且去除-
        String saveFileName= UUID.randomUUID().toString().replaceAll("-","")+".jpg";
        try {
            URL url = new URL(imgUrl);
            connection = (HttpURLConnection)url.openConnection();
            connection.connect();
            //将文件传入缓冲区中
            in = new BufferedInputStream(connection.getInputStream());
            //将文件读取出来
            out = new FileOutputStream(baseFilePath+ File.separator+saveFileName);

            while ((len = in.read(buf)) != -1) {
                out.write(buf, 0, len);
            }
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
                out.close();
                connection.disconnect();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return  saveFileName;
    }

    /**
     * 跳到新闻添加添加页面
     * @param model
     * @return
     */
    @RequestMapping("addPage")
    public String addPage(Model model){
        return "news/add";
    }

    /**
     * 新闻添加,添加至审核新闻列表
     * */
    @RequestMapping("add")
    @ResponseBody
    public ResponseBean addCheckNews(CheckNews news, HttpSession session){
        logger.debug("addSysNews:"+news);

        news.setUserId(ToolsUtils.getLoginUserId(session));
        news.setUserName(ToolsUtils.getLoginUserName(session));
        Long categoryId = news.getCategoryId();
        news.setCategoryName(newsCategoryService.getById(categoryId)==null?"":newsCategoryService.getById(categoryId).getName());
        boolean i = checkNewsService.save(news);
        logger.debug("存放至审核，保存后的news:"+news);
        return ResultUtil.successData(news);
    }
    /**
     * 跳转到新闻修改页面
     * @param id
     * @param model
     * @return
     */
    @RequestMapping("/editPage/{id}")
    public String editPage(@PathVariable Long id, Model model) {
        model.addAttribute("news", newsService.getById(id));
        return "news/edit";
    }
    /**
     * 新闻修改
     * @param news
     * @return
     */
    @RequestMapping("/edit")
    @ResponseBody
    public ResponseBean updateById(SysNews news,HttpSession session) {
        if (news == null||news.getId()==null) {
            return ResultUtil.error(CommonEnum.BAD_PARAM);
        }
        Long categoryId = news.getCategoryId();
        news.setCategoryName(newsCategoryService.getById(categoryId)==null?"":newsCategoryService.getById(categoryId).getName());
        news.setUserId(ToolsUtils.getLoginUserId(session));
        news.setUserName(ToolsUtils.getLoginUserName(session));
        news.setUpdateTime(LocalDateTime.now());
        boolean i = newsService.updateById(news);
        return ResultUtil.successData(news);
    }

    /**
     * 新闻转发
     * @param news
     * @return
     */
    @RequestMapping("/forward")
    @ResponseBody
    public ResponseBean forwardnews(SysNews news,HttpSession session) {
        news.setChannel(2);
        news.setChannelNewsId(news.getId());
        news.setId(null);
        Long categoryId = news.getCategoryId();
        news.setCategoryName(newsCategoryService.getById(categoryId)==null?"":newsCategoryService.getById(categoryId).getName());
        news.setUserId(ToolsUtils.getLoginUserId(session));
        news.setUserName(ToolsUtils.getLoginUserName(session));
        news.setUpdateTime(LocalDateTime.now());
        boolean i = newsService.save(news);
        //往转发表插入数据
        Long channelNewsId = news.getChannelNewsId();
        SysNews channelNews = newsService.getById(channelNewsId);
        NewsForward newsForward=new NewsForward();
        newsForward.setNewsId(channelNewsId);
        newsForward.setNewsTitle(channelNews.getTitle());
        newsForward.setUserId(ToolsUtils.getLoginUserId(session));
        newsForward.setUserName(ToolsUtils.getLoginUserName(session));
        forwardService.save(newsForward);
        return ResultUtil.successData(news);
    }

    /**
     * 跳转列表页面
     * @return
     */
    @RequestMapping("/listPage")
    public String newsListPage() {
        return "news/list";
    }

    /**
     * 新闻列表查询
     * @param pageNum 页码
     * @param pageSize 每页大小
     * @param queryParam 查询参数
     * @param vagueParam 模糊参数
     * @return
     */
    @ApiOperation("获取新闻列表")
    @RequestMapping("/list/{pageNum}/{pageSize}")
    @ResponseBody
    public ResponseBean getList(@PathVariable Integer pageNum,@PathVariable Integer pageSize,
                                SysNews queryParam,String vagueParam) {
        logger.debug("查询新闻列表参数："+queryParam+",pageNum:"+pageNum+",pageSize:"+pageSize);
        QueryWrapper<SysNews> queryWrapper=new QueryWrapper<>();
        Long categoryId = queryParam.getCategoryId();
        queryWrapper.eq(categoryId!=null,"category_id",categoryId);
        String title = queryParam.getTitle();
        queryWrapper.like(!StringUtils.isEmpty(title),"title",title);
        if(!StringUtils.isEmpty(vagueParam)){
            // and ( title like '%XXXX%' or theme like '%YYYY%')
            queryWrapper.and(
                    e->e.like("title",vagueParam)
                    .or()
                    .like("theme",vagueParam)
            );
        }
        queryWrapper.orderByDesc("id");
        IPage<SysNews> indexPage = new Page<>(pageNum, pageSize);
        IPage<SysNews> newsIPage = newsService.page(indexPage, queryWrapper);
        logger.debug("获取的新闻列表："+newsIPage);
        Map resultMap = ToolsUtils.wrapperResult(newsIPage, "newsList");
        return ResultUtil.successData(resultMap);
    }

    /**
     * 新闻转发
     * */
    @RequestMapping("/forwardPage/{id}")
    public String forwardPage(@PathVariable Long id,Model model){
        SysNews news = newsService.getById(id);
        model.addAttribute("news",news);
        return "home/news/forward";
    }
    /**
     * 跳到前台新闻编辑页面
     * @return
     */
    @RequestMapping("homeEditPage/{id}")
    public String homeEditPage(@PathVariable Long id,Model model){
        SysNews news = newsService.getById(id);
        model.addAttribute("news",news);
        return "home/news/edit";
    }
    /**
     * 跳到前台猜你喜欢列表页面
     * @return
     */
    @RequestMapping("recommendListPage")
    public String recommendListPage(Model model){
        return "home/recommend/list";
    }

    /**
     * 跳到前台我的关注列表页面
     * @return
     */
    @RequestMapping("attentionListPage")
    public String attentionListPage(Model model){
        return "home/attention/list";
    }

    //跳到前台我的发布页面
    @RequestMapping("mypublishPage")
    public String mypublishPage(Model model){
        return "home/mypublish/list";
    }


    /**
     * 跳到前台系统特色页面
     * @return
     */
    @RequestMapping("featureListPage")
    public String featureListPage(String categoryId,Model model){
        model.addAttribute("categoryId",StringUtils.isEmpty(categoryId)?"1":categoryId);
        return "home/feature/list";
    }

    /**
     * 跳到前台新闻发布页面
     * @return
     */
    @RequestMapping("homeAddPage")
    public String homeAddPage(){
        return "home/news/add";
    }

    //跳到前台热点新闻列表页面
    @RequestMapping("/homeListPage")
    public String homeListPage(){
        return "home/news/list";
    }
    //跳到前台新闻图示列表页面
    @RequestMapping("/homeListPicPage")
    public String homeListPicPage(){
        return "home/news/listpic";
    }

    //跳到前台新闻详情页面

    /**
     *  @RequestMapping+return string  ===返回到某个页面
     * @param id
     * @param model
     * @param session
     * @return
     */
    @RequestMapping("/homeDetail/{id}")
    public String homeDetail(@PathVariable Long id,Model model,HttpSession session){
        SysNews news = newsService.getById(id);
        model.addAttribute("news",news);
        Long userId = news.getUserId();
        //发布新闻的用户
        SysUser newsUser = userService.getById(userId);
        model.addAttribute("newsUser",newsUser);
        SysUser loginUser = ToolsUtils.getLoginUser(session);
        if(loginUser!=null){
            QueryWrapper<UserAttention> attentionWrapper=new QueryWrapper<>();
            attentionWrapper.eq("from_user_id",loginUser.getId()).eq("to_user_id",userId);
            List<UserAttention> list = attentionService.list(attentionWrapper);
            model.addAttribute("if_attention",!ToolsUtils.isEmpty(list));//false表示需要关注，true标识不需要关注

            QueryWrapper<NewsFavor> favorQueryWrapper=new QueryWrapper<>();
            favorQueryWrapper.eq("news_id",id).eq("user_id",loginUser.getId());
            List<NewsFavor> favorList = favorService.list(favorQueryWrapper);
            model.addAttribute("if_favor",!ToolsUtils.isEmpty(favorList));
        }

        return "home/news/detail";
    }


    /**
     * @RequestMapping+@ResponseBody=返回json格式数据，不跳页面
     * @param pageNum
     * @param pageSize
     * @param queryParam
     * @param session
     * @return
     */
    @ApiOperation("获取我的发布列表")
    @RequestMapping("/mypublish/{pageNum}/{pageSize}")
    @ResponseBody
    public ResponseBean mypublish(@PathVariable Integer pageNum,@PathVariable Integer pageSize,
                                SysNews queryParam,HttpSession session) {
        logger.debug("查询热门新闻列表参数："+queryParam+",pageNum:"+pageNum+",pageSize:"+pageSize);
        QueryWrapper<SysNews> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("user_id",ToolsUtils.getLoginUserId(session));
        IPage<SysNews> newsIPage = new Page<>(pageNum,pageSize);
        IPage<SysNews> listPage = newsService.page(newsIPage, queryWrapper);
        Map resultMap = ToolsUtils.wrapperResult(listPage, "mypublishList");
        return ResultUtil.successData(resultMap);
    }


    @ApiOperation("获取热门新闻列表")
    @RequestMapping("/hotlist/{pageNum}/{pageSize}")
    @ResponseBody
    public ResponseBean hotlist(@PathVariable Integer pageNum,@PathVariable Integer pageSize,
                                SysNews queryParam,String vagueParam) {
        logger.debug("查询热门新闻列表参数："+queryParam+",pageNum:"+pageNum+",pageSize:"+pageSize);
        Date startTime=DateUtils.addMinute(new Date(),-10);
        Date endTime=new Date();
        List<SysNews> newsList = newsService.hotList(startTime, endTime);
        logger.debug("获取的热门新闻列表："+newsList);
        IPage<SysNews> newsIPage = new Page<>(pageNum,pageSize);
        newsIPage.setRecords(newsList);
        Map resultMap = ToolsUtils.wrapperResult(newsIPage, "hotNewsList");
        return ResultUtil.successData(resultMap);
    }

    @ApiOperation("获取系统特色新闻列表")
    @RequestMapping("/featureList/{pageNum}/{pageSize}")
    @ResponseBody
    public ResponseBean featureList(@PathVariable Integer pageNum,@PathVariable Integer pageSize,
                                SysNews queryParam,String vagueParam) {
        logger.debug("查询系统特色新闻列表参数："+queryParam+",pageNum:"+pageNum+",pageSize:"+pageSize);
        QueryWrapper<SysNews> queryWrapper=new QueryWrapper<>();
//        获取新闻分类id
        Long categoryId = queryParam.getCategoryId();
        if(categoryId==null){
            queryParam.setCategoryId(1L);
        }
        queryWrapper.allEq(ToolsUtils.convertObjToMap(queryParam),false);
        queryWrapper.orderByDesc("id");
        IPage<SysNews> indexPage = new Page<>(pageNum, pageSize);
        IPage<SysNews> newsIPage = newsService.page(indexPage, queryWrapper);
        logger.debug("获取的系统特色新闻列表："+newsIPage);
        Map resultMap = ToolsUtils.wrapperResult(newsIPage, "featureList");
        return ResultUtil.successData(resultMap);
    }


    @ApiOperation("获取推荐新闻列表")
    @RequestMapping("/recommendList/{pageNum}/{pageSize}")
    @ResponseBody
    public ResponseBean recommendList(@PathVariable Integer pageNum,@PathVariable Integer pageSize,
                                SysNews queryParam,HttpSession session) {
        logger.debug("查询推荐新闻列表参数："+queryParam+",pageNum:"+pageNum+",pageSize:"+pageSize);
        QueryWrapper<SysNews> queryWrapper=new QueryWrapper<>();
        queryWrapper.orderByDesc("id");
        IPage<SysNews> indexPage = new Page<>(pageNum, pageSize);
        SysUser loginUser = ToolsUtils.getLoginUser(session);
        if(loginUser!=null){
            List<Long> idList=getRecommendIdList(loginUser);
            queryWrapper.in(ToolsUtils.isNotEmpty(idList),"id",idList);
        }
        IPage<SysNews> newsIPage = newsService.page(indexPage, queryWrapper);
        logger.debug("获取的推荐新闻列表："+newsIPage);
        Map resultMap = ToolsUtils.wrapperResult(newsIPage, "recommendList");
        return ResultUtil.successData(resultMap);
    }

    /**
     * 用户  物品-电影 新闻   评分(关系数，评分/评论数/转发数/点赞数)
     * @param loginUser
     * @return
     */
    private List<Long> getRecommendIdList(SysUser loginUser){
        List<SysNews> newsList = newsService.list();
        List<NewsForward> forwardList = forwardService.list();
        List<NewsFavor> favorList = favorService.list();
        List<NewsComment> commentList = commentService.list();
        List<SysUser> userList = userService.list();
        List<NewsNumber> newsNumberList=new ArrayList<>();
        for(SysNews news:newsList){
            for(SysUser user:userList){
                NewsNumber newsNumber=new NewsNumber();
                Long userId = user.getId();
                Long newsId = news.getId();
                newsNumber.setUserId(userId);
                newsNumber.setNewsId(newsId);
                long forward = forwardList.stream().filter(e -> e.getUserId().toString().equals(userId.toString())&&e.getNewsId().toString().equals(newsId.toString())).count();
                long favor = favorList.stream().filter(e -> e.getUserId().toString().equals(userId.toString())&&e.getNewsId().toString().equals(newsId.toString())).count();
                long comment = commentList.stream().filter(e -> e.getUserId().toString().equals(userId.toString())&&e.getNewsId().toString().equals(newsId.toString())).count();
                newsNumber.setNumber(forward+favor+comment);
                if(newsNumber.getNumber()>0){
                    newsNumberList.add(newsNumber);
                }
            }
        }
        List<String> calculate = CollaborativeAlgorithm.calculate(loginUser.getId().intValue(), newsNumberList);
        List<Long> collect = calculate.stream().map(e -> Long.parseLong(e)).collect(Collectors.toList());
        return collect;
    }


    @ApiOperation("获取关注的用户新闻列表")
    @RequestMapping("/attentionList/{pageNum}/{pageSize}")
    @ResponseBody
    public ResponseBean attentionList(@PathVariable Integer pageNum,@PathVariable Integer pageSize,
                                SysNews queryParam,HttpSession session) {
        logger.debug("查询关注的新闻列表参数："+queryParam+",pageNum:"+pageNum+",pageSize:"+pageSize);
        QueryWrapper<SysNews> queryWrapper=new QueryWrapper<>();
        queryWrapper.orderByDesc("id");
        SysUser loginUser = ToolsUtils.getLoginUser(session);
        IPage<SysNews> indexPage = new Page<>(pageNum, pageSize);
        //如果当前登录用户不为空，则增加查询条件：从关注的用户的新闻里面查找
        if(loginUser!=null){
            QueryWrapper<UserAttention> attentionWrapper=new QueryWrapper<>();
            attentionWrapper.eq("from_user_id",loginUser.getId());
            List<UserAttention> attentionList = attentionService.list(attentionWrapper);
            List<Long> toUserIdList = attentionList.stream().map(e -> e.getToUserId()).collect(Collectors.toList());
            queryWrapper.in(ToolsUtils.isNotEmpty(toUserIdList),"user_id",toUserIdList);
        }
        //获取登录用户的关注用户列表
        IPage<SysNews> newsIPage = newsService.page(indexPage, queryWrapper);
        logger.debug("获取的关注新闻列表："+newsIPage);
        Map resultMap = ToolsUtils.wrapperResult(newsIPage, "attentionList");
        return ResultUtil.successData(resultMap);
    }

    @RequestMapping("deleteBatchByIds")
    @ResponseBody
    public ResponseBean deleteBatchByIds(@RequestParam List<Integer> idList){
        logger.debug("deleteBatchByIds:"+idList);
        if(idList==null||idList.isEmpty()){
            return ResultUtil.error(CommonEnum.BAD_PARAM);
        }
        boolean delete = newsService.removeByIds(idList);
        logger.debug("批量删除结果："+delete);
        return ResultUtil.success() ;
    }

    @RequestMapping("deleteById")
    @ResponseBody
    public ResponseBean deleteById(@RequestParam Long id){
        if(id==null||id<0){
            return ResultUtil.error(CommonEnum.BAD_PARAM);
        }
        boolean delete = newsService.removeById(id);
        return ResultUtil.success() ;
    }

    @ApiOperation("获取新闻详情")
    @RequestMapping("detail/{id}")
    public String detailPage(@PathVariable Long id, Model model){
        SysNews news = newsService.getById(id);
        model.addAttribute("news",news);
        return "news/detail";
    }


}
